package com.atomos.system
{
	import com.atomos.strategy.emission.EmissionStrategy;
	import com.bourre.collection.WeakCollection;
	import com.kairos.engine.RTAnimation;	

	/**
	 * A <code>ParticleSystem</code> is a structure witch both contains
	 * particles and methods to apply on them. Use a particle system each
	 * time you want to manage particles with specific behaviors.
	 * 
	 * <p>That interface defines rules that a <code>ParticleSystem</code>
	 * have to follow when dealing with particles. For example, a system
	 * should use <code>EmissionStrategy</code> object to perform creation
	 * of particles in time. That's not the system that creates particles,
	 * it just handle them, in the same way the system don't act itself
	 * on particles, it simply own strategies that will act on particles.</p>
	 * 
	 * <p>That interface don't defines rules a system have to follow concerning
	 * initializations and actions methods to apply to particles. It's let at
	 * the convenience of concrets classes that implement <code>ParticleSystem</code>
	 * witch can create and use any kind of strategies to performs particles life.</p>
	 * 
	 * <p>The only object that is allowed to handle particle systems is the 
	 * <code>ParticleManager</code>, systems have to register themselves to
	 * it when instanciated. That registration iss necessary in order to provide
	 * a global access to all systems created within Atomos.</p>
	 * 
	 * @author  Cédric Néhémie 
	 * @see		com.atomos.particle.Particle
	 * @see		com.atomos.particle.ParticleManager
	 * @see		com.atomos.strategy.emission.EmissionStrategy
	 */
	public interface ParticleSystem extends RTAnimation
	{
		/**
		 * Starts an emission of particles according to the rules defined in
		 * the passed-in <code>EmissionStrategy</code>. A particle system may
		 * own several emissions at the same time.
		 * 
		 * <p>If a system witch use strategy to perform particles creation receive
		 * a null object in the <code>emit</code>
		 * 
		 * <p>If a system don't use <code>EmissionStrategy</code> to perform the
		 * particles creation it have to throw an <code>UnsupportedOperationException</code>
		 * in the <code>emit</code> method and have to provide an alternative method
		 * to perform emission.</p>
		 * 
		 * @param emission	<code>EmissionStrategy</code> to perform
		 * @throws com.bourre.error.NullPointerException The passed-in strategy is null
		 * @throws com.bourre.error.UnsupportedOperationException The current
		 * 		   class don't support the <code>emit<code> method
		 */
		function emit ( emission : EmissionStrategy = null ) : void;
	
		/**
		 * Deletes the reference to that system owned by the <code>ParticleSystem</code>.
		 * 
		 * <p>As particle systems are automatically stored in the mangager, it can occurs
		 * memory leak if they were not properly removed from it when they have finish to
		 * be used by the application. Be sure that you call the <code>release</code> method
		 * when you want to remove a system.</p>
		 * 
		 * <p>Notice that a call of release don't have to remove particles stored by the system.
		 * As particles can be stored by several systems simultaneously, if particles should
		 * removed when releasing a system, then other systems that shared the same particles
		 * will loose reference to them.</p>
		 */
		function release () : void;
		
		/**
		 * Defines on witch particles the current system will work.
		 * 
		 * <p>That function is usefull when using <code>ParticleManager</code>
		 * methods to get reference to particles across several other systems.
		 * In that way you could affect specifical behaviors to a small set of
		 * particles independently of their original system's behaviors.</p>
		 * 
		 * <p>Particle systems that wouldn't support that method have to throw
		 * an <code>UnsupportedOperationException</code>.</p>
		 * 
		 * @param particles	<code>WeakCollection</code> of particles to handle
		 * @throws com.bourre.error.UnsupportedOperationException That method
		 * 		   isn't supported by the current class
		 * @throws com.bourre.error.NullPointerException The passed-in collection
		 * 	       is null
		 */
		function setParticles ( particles : WeakCollection ) : void;
		
		/**
		 * Returns a reference to the internal collection that hold particles.
		 * 
		 * <p>The returned collection have to be a reference to the current
		 * system's collection, not a copy. As particles are stored as weak
		 * references, objects that will get a reference to that collection
		 * will be automatically noticed when particles are added or removed
		 * from that collection without having any risk of memory leaks.</p>
		 * 
		 * @return <code>WeakCollection</code> of particles stored in the system
		 */
		function getParticles () : WeakCollection;
		
		/**
		 * Returns the number of particles currently stored in the system.
		 * 
		 * @return <code>Number</code> of particles stored in the system
		 */
		function getParticlesCount () : Number;
		
		/**
		 * Returns a collection of all emissions currently running in the system.
		 * 
		 * <p>If a concret system don't use <code>EmissionStrategy</code> it have
		 * to return an empty collection.</p>
		 * 
		 * @return <code>WeakCollection</code> of all <code>EmissionStrategy</code>
		 * 		   owned by the current <code>ParticleSystem</code>
		 */
		function getEmissions () : WeakCollection;
		
		/**
		 * Returns the number of emissions currently running in the system.
		 * 
		 * <p>If a concret system don't use <code>EmissionStrategy</code> it have
		 * to return 0.</p>
		 * 
		 * @return <code>Number</code> of emissions currently running in the system
		 */
		function getEmissionsCount () : Number;
		
		/**
		 * Returns <code>true</code> if there is at least one emission running
		 * in the current system, either <code>false</code>.
		 * 
		 * @return <code>true</code> if there is an emission running in the system,
		 * 		   either <code>false</code>
		 */
		function isEmitting () : Boolean;
	}
}